package xutils

import (
	"bytes"
	"encoding/binary"
	"github.com/shopspring/decimal"
	"math"
	"math/rand"
	"time"
)

func IntToBytes(i interface{}) []byte {
	buf := bytes.NewBuffer([]byte{})
	switch t := i.(type) {
	case int64, uint64, int32, uint32, int16, uint16, int8, uint8:
		binary.Write(buf, binary.BigEndian, t)
	case int:
		if t > math.MaxInt32 {
			binary.Write(buf, binary.BigEndian, int64(t))
		} else {
			binary.Write(buf, binary.BigEndian, int32(t))
		}
	case uint:
		if t > math.MaxUint32 {
			binary.Write(buf, binary.BigEndian, uint64(t))
		} else {
			binary.Write(buf, binary.BigEndian, uint32(t))
		}
	}

	return buf.Bytes()
}

func BytesToInt(b []byte) int64 {
	buf := bytes.NewBuffer(b)
	switch len(b) {
	case 1:
		return int64(b[0])
	case 2:
		var x int16
		binary.Read(buf, binary.BigEndian, &x)
		if x > 0 {
			return int64(x)
		}
		return int64(math.MaxUint16) + int64(x) + 1
	case 4:
		var x int32
		binary.Read(buf, binary.BigEndian, &x)
		if x > 0 {
			return int64(x)
		}
		return int64(math.MaxUint32) + int64(x) + 1
	case 8:
		var x int64
		binary.Read(buf, binary.BigEndian, &x)
		return x
	default:
		return 0
	}
}

func RandInt(min, max int64) int64 {
	if min >= max {
		return max
	}
	rand.Seed(time.Now().UnixNano())
	return rand.Int63n(max-min) + min
}

func RandFloat(min, max float64) float64 {
	rand.Seed(time.Now().UnixNano())
	return min + rand.Float64()*(max-min)
}

func Round(val float64, p int32) float64 {
	v, _ := decimal.NewFromFloat(val).Round(p).Float64()
	return v
}

func UniqueInt64(data []int64) []int64 {
	dMap := make(map[int64]struct{})
	for _, v := range data {
		dMap[v] = struct{}{}
	}
	tmp := make([]int64, len(dMap))
	i := 0
	for k := range dMap {
		tmp[i] = k
		i++
	}

	return tmp
}
